package com.cjkj.system.service.impl;

import com.cjkj.common.core.constant.CacheConstants;
import com.cjkj.common.core.constant.PatVisitStatusConstants;
import com.cjkj.common.core.constant.SecurityConstants;
import com.cjkj.common.core.domain.R;
import com.cjkj.common.core.exception.ServiceException;
import com.cjkj.common.core.utils.DateUtils;
import com.cjkj.common.core.utils.uuid.IdUtils;
import com.cjkj.common.redis.service.RedisService;
import com.cjkj.common.security.utils.SecurityUtils;
import com.cjkj.system.api.RemoteAppService;
import com.cjkj.system.api.domain.THospitalUser;
import com.cjkj.system.api.model.AppletLoginUser;
import com.cjkj.system.domain.TPatVisit;
import com.cjkj.system.domain.dto.HospitalUserReq;
import com.cjkj.system.domain.vo.HospitalUserVo;
import com.cjkj.system.mapper.THospitalUserMapper;
import com.cjkj.system.mapper.TPatVisitMapper;
import com.cjkj.system.service.ITHospitalUserService;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * 医院用户Service业务层处理
 * 
 * @author cjkj
 * @date 2024-08-30
 */
@Service
public class THospitalUserServiceImpl implements ITHospitalUserService 
{
    @Resource
    private THospitalUserMapper tHospitalUserMapper;
    @Resource
    private TPatVisitMapper patVisitMapper;
    @Resource
    private RemoteAppService remoteAppService;
    @Resource
    private RedisService redisService;
    private final static String ACCESS_TOKEN = CacheConstants.WX_LOGIN_TOKEN_KEY;

    /**
     * 查询医院用户
     * 
     * @param userId 医院用户主键
     * @return 医院用户
     */
    @Override
    public THospitalUser selectTHospitalUserByUserId(String userId)
    {
        return tHospitalUserMapper.selectTHospitalUserByUserId(userId);
    }

    @Override
    public THospitalUser getUserByUserName(String userName) {
        return tHospitalUserMapper.selectTHospitalUserByUserName(userName);
    }

    @Override
    @Transactional
    @GlobalTransactional(rollbackFor = Exception.class)
    public int resetUserPwd(String userName, String password) {

        // 清空医生账号信息
        R<?> r = remoteAppService.clearDoctorInfo(userName, SecurityConstants.INNER);
        if (!R.isSuccess(r)) {
            throw new ServiceException("清空医生账号信息出错！");
        }

        // 修改密码
        int i = tHospitalUserMapper.resetUserPwd(userName, password);
        if (i <= 0) {
            throw new ServiceException("修改密码出错！");
        }

        // 获取用户登录缓存
        Collection<String> keys = redisService.keys(ACCESS_TOKEN + "*");
        for (String key : keys){
            // 强退绑定了当前医生账号的用户
            AppletLoginUser loginUser = redisService.getCacheObject(key);
            if (loginUser != null && userName.equals(loginUser.getDoctor())){
                redisService.deleteObject(key);
            }
        }

        return i;
    }

    @Override
    public List<HospitalUserVo> selectTHospitalUserList(HospitalUserReq req) {
        return tHospitalUserMapper.selectTHospitalUserList(req);
    }

    /**
     * 新增医院用户
     * 
     * @param tHospitalUser 医院用户
     * @return 结果
     */
    @Override
    public int add(THospitalUser tHospitalUser)
    {
        String userName = tHospitalUser.getUserName();
        THospitalUser user = tHospitalUserMapper.selectTHospitalUserByUserName(userName);
        if(user != null) {
            throw new ServiceException("用户账号：" + userName + "已存在！");
        }

        Date nowDate = DateUtils.getNowDate();
        String username = SecurityUtils.getUsername();

        tHospitalUser.setUserId(IdUtils.fastSimpleUUID());
        tHospitalUser.setPassword(SecurityUtils.encryptPassword(tHospitalUser.getPassword()));
        tHospitalUser.setCreateTime(nowDate);
        tHospitalUser.setCreateBy(username);
        tHospitalUser.setUpdateTime(nowDate);
        tHospitalUser.setUpdateBy(username);
        return tHospitalUserMapper.insertTHospitalUser(tHospitalUser);
    }

    /**
     * 修改医院用户
     * 
     * @param tHospitalUser 医院用户
     * @return 结果
     */
    @Override
    public int updateTHospitalUser(THospitalUser tHospitalUser)
    {
        String userName = tHospitalUser.getUserName();
        THospitalUser user = tHospitalUserMapper.selectTHospitalUserByUserName(userName);
        if(user != null && !user.getUserId().equals(tHospitalUser.getUserId())) {
            throw new ServiceException("用户账号：" + userName + "已存在！");
        }

        tHospitalUser.setUpdateBy(SecurityUtils.getUsername());
        tHospitalUser.setUpdateTime(DateUtils.getNowDate());
        return tHospitalUserMapper.updateTHospitalUser(tHospitalUser);
    }

    /**
     * 删除医院用户信息
     * 
     * @param userId 医院用户主键
     * @return 结果
     */
    @Override
    public int deleteUserById(String userId)
    {

        // 判断是否还有未出院患者
        List<TPatVisit> tPatVisits = patVisitMapper.selectByDoctorId(userId, null, PatVisitStatusConstants.VISIT_STATUS_UNDERWAY);
        if(! tPatVisits.isEmpty()) {
            throw new ServiceException("该账号下还有未结束就诊的患者，不能删除！");
        }

        return tHospitalUserMapper.deleteTHospitalUserByUserId(userId);
    }

    @Override
    public List<HospitalUserVo> getUserByDept(String hospitalId, String deptId) {
        return tHospitalUserMapper.selectUserByDept(hospitalId, deptId);
    }

    @Override
    public boolean verifyUserPassword(String userId) {
        THospitalUser hospitalUser = tHospitalUserMapper.selectTHospitalUserByUserId(userId);
        return hospitalUser != null && !SecurityUtils.matchesPassword("123456", hospitalUser.getPassword());
    }
}
